package com.example.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.common.core.constants.Constants;
import com.example.common.core.constants.HttpConstants;
import com.example.common.core.domain.LoginUser;
import com.example.common.core.domain.R;
import com.example.common.core.domain.vo.LoginUserVO;
import com.example.common.core.enums.ResultCode;
import com.example.common.core.enums.UserIdentity;
import com.example.common.core.utils.BCryptUtils;
import com.example.common.core.utils.ThreadLocalUtil;
import com.example.common.redis.service.RedisService;
import com.example.common.security.exception.ServiceException;
import com.example.common.security.service.TokenService;
import com.example.user.domain.teacher.Teacher;
import com.example.user.domain.teacher.dto.TeacherSaveDTO;
import com.example.user.domain.teacher.vo.TeacherDetailVO;
import com.example.user.manger.StudentCacheManager;
import com.example.user.manger.TeacherCacheManager;
import com.example.user.mapper.teacher.TeacherMapper;
import com.example.user.service.ITeacherService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.example.common.core.constants.Constants.USER_ID;

@Service
@Transactional(readOnly = true)
public class TeacherServiceImpl implements ITeacherService {
    @Autowired
    private RedisService redisService;
    @Autowired
    private StudentCacheManager studentCacheManager;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private TeacherMapper teacherMapper;

    @Autowired
    private TeacherCacheManager teacherCacheManager;

    @Value("${jwt.secret}") // 用于生成JWT token
    private String secret;

    @Value("${file.oss.downloadUrl}") // 头像存储地址，阿里云OSS
    private String downloadUrl;

    private String defaultAvatar = "head_image.png";
    


    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<String> login(String email, String password) {
        // 检查用户是否存在
        // 邮箱就是账户是必须填写的
        Teacher teacher = teacherMapper.selectOne(new LambdaQueryWrapper<Teacher>()
                .select(Teacher::getPassword, Teacher::getTeacherId,Teacher::getNickName, Teacher::getHeadImage)
                .eq(Teacher::getEmail, email));
        if(teacher == null){
            return R.fail(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        if (BCryptUtils.matchesPassword(password, teacher.getPassword())) {
            String token = tokenService.createToken(teacher.getTeacherId(),
                    secret, UserIdentity.TEACHER.getValue(), teacher.getNickName(), teacher.getHeadImage());
            return R.ok(token);
        }
        return R.fail(ResultCode.FAILED_LOGIN);

    }

    @Override
    public R<LoginUserVO> info(String token) {
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        LoginUser loginUser = tokenService.getLoginUser(token, secret);
        if (loginUser == null) {
            return R.fail();
        }
        LoginUserVO loginUserVO = new LoginUserVO();
        loginUserVO.setNickName(loginUser.getNickName());
        if(StrUtil.isEmpty(loginUser.getHeadImage())){
            loginUser.setHeadImage(defaultAvatar);
        }
        loginUserVO.setHeadImage(downloadUrl + loginUser.getHeadImage());
        return R.ok(loginUserVO);
    }

    @Override
    public R<TeacherDetailVO> detail(String token) {
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        Teacher teacher = teacherMapper.selectById(ThreadLocalUtil.get(USER_ID,Long.class));
        if(teacher == null){
            throw new ServiceException(ResultCode.FAILED_NOT_EXISTS);
        }
        TeacherDetailVO teacherDetailVO = new TeacherDetailVO();
        LoginUser loginUser = tokenService.getLoginUser(token, secret);
        if (loginUser == null) {
            return R.fail();
        }
        if(StrUtil.isEmpty(loginUser.getHeadImage())){
            loginUser.setHeadImage(defaultAvatar);
        }
        teacher.setHeadImage(downloadUrl + loginUser.getHeadImage());
        BeanUtil.copyProperties(teacher,teacherDetailVO);
        return R.ok(teacherDetailVO);
    }

    // 这里也是只编辑基本信息，不编辑头像
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int edit(TeacherSaveDTO teacherEditDTO) {
        Teacher oldTeacher = teacherMapper.selectById(teacherEditDTO.getTeacherId());
        if(oldTeacher == null){
            throw new ServiceException(ResultCode.FAILED_NOT_EXISTS);
        }
        oldTeacher.setNickName(teacherEditDTO.getNickName());
        oldTeacher.setEmail(teacherEditDTO.getEmail());
        oldTeacher.setPhone(teacherEditDTO.getPhone());
        oldTeacher.setIdentificationCard(teacherEditDTO.getIdentificationCard());
        oldTeacher.setHireDate(teacherEditDTO.getHireDate());
        oldTeacher.setBirthday(teacherEditDTO.getBirthday());
        oldTeacher.setAddress(teacherEditDTO.getAddress());
        oldTeacher.setSex(teacherEditDTO.getSex());
        oldTeacher.setTitle(teacherEditDTO.getTitle());
        oldTeacher.setBio(teacherEditDTO.getBio());
        return teacherMapper.updateById(oldTeacher);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean logout(String token) {
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        return tokenService.deleteLoginUser(token, secret);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateHeadImage(String headImage) {
        Long teacherId = ThreadLocalUtil.get(USER_ID, Long.class);
        if(teacherId == null){
            throw new ServiceException(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        Teacher teacher = teacherMapper.selectById(teacherId);
        teacher.setHeadImage(headImage);
        // redis上会存储用户的登录信息（昵称，头像），所以更新头像后需要刷新缓存
        teacherCacheManager.refreshTeacher(teacher);
        tokenService.refreshLoginUser(teacher.getNickName(),teacher.getHeadImage(),
                ThreadLocalUtil.get(Constants.USER_KEY, String.class));
        return teacherMapper.updateById(teacher);
    }
}
